package vip.xumy.core.utils;

import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import vip.xumy.core.exception.CoreException;

/**	All rights reserved
 *	author:mengyxu
 *	date:2019年5月17日
 */

public class DateUtil {
	public static final String FORMAT10_LINE_DDMMYYYY = "dd-MM-yyyy";
	public static final String FORMAT10_LINE_MMDDYYYY = "MM-dd-yyyy";
	public static final String FORMAT10_LINE_YYYYMMDD = "yyyy-MM-dd";
	
	public static final String FORMAT10_SLASH_DDMMYYYY = "dd/MM/yyyy";
	public static final String FORMAT10_SLASH_MMDDYYYY = "MM/dd/yyyy";
	public static final String FORMAT10_SLASH_YYYYMMDD = "yyyy/MM/dd";
	
	public static final String FORMAT19_LINE_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";

	public static final String FORMAT8_DDMMYYYY = "ddMMyyyy";
	public static final String FORMAT8_MMDDYYYY = "MMddyyyy";
	public static final String FORMAT8_YYYYMMDD = "yyyyMMdd";
	
	public static final String FORMAT3_YYM = "yy年M月";
	public static final String FORMAT2_MD = "M月d日";
	public static final String FORMAT2_DH = "d日H时";
	
	public static final String FORMAT10_YYYYMMDDHH = "yyyyMMddHH";
	
	public static final String FORMAT6_YYYYMM = "yyyyMM";
	public static final String FORMAT8_YYYYMM = "yyyy年MM月";
	
	public static final String FORMAT14_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
	public static final String FORMAT_GMT_8 = "EEE MMM dd yyyy HH:mm:ss 'GMT+0800(中国标准时间)'";
	
	public static final String FORMAT20_LINE_YYYYMMDDTHHMMSS = "yyyy-MM-dd'T'HH:mm:ss";
		
	
	private DateUtil(){
		//Add a private constructor to hide the implicit public one.
	}
	
	/**
	 * <p>
	 * Convert a date string from <code>srcPattern</code> to <code>destPattern</code>。
	 * </p>
	 * @param dateStr
	 * @param srcPattern
	 * @param destPattern
	 * @return
	 * @throws CoreException
	 */
	public static String convert(String dateStr, String srcPattern, String destPattern) throws CoreException{
		if (dateStr == null){
			return null;
		}
		
		Date date = parse(dateStr, srcPattern);
		return format(date, destPattern);
	}
	
	/**
	 * Format a date with specific String pattern.
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String format(Date date, String pattern){
		DateFormat formatter = new SimpleDateFormat(pattern);
		
		return formatter.format(date);
	}
	
	
	/**
	 * Format a date with specific String pattern.
	 * @param date
	 * @param pattern
	 * @Param locale
	 * @return
	 */
	public static String format(Date date, String pattern, Locale locale){
		DateFormat formatter = new SimpleDateFormat(pattern, locale);
		
		return formatter.format(date);
	}
	
	/**
	 * Parse a string to a date with pattern.
	 * @param src
	 * @param pattern
	 * @return
	 * @throws CoreException
	 */
	public static Date parse(String src, String pattern) throws CoreException{
		DateFormat formatter = new SimpleDateFormat(pattern);
		try {
			return formatter.parse(src);
		} catch (ParseException e) {
			String message = "Connect convert to date. Unexpected pattern [{0}] for value [{1}].";
			throw new CoreException(MessageFormat.format(message, pattern, src), e);
		}
	}
	
	public static int compare(String src, String dest, String pattern) throws CoreException{
		Date srcDate = parse(src, pattern);
		Date destDate = parse(dest, pattern);
		
		return srcDate.compareTo(destDate);
	}
	
	public static long diff(String src, String dest, String pattern) throws CoreException{
		Date srcDate = parse(src, pattern);
		Date destDate = parse(dest, pattern);
		
		return (destDate.getTime()-srcDate.getTime())/(1000*60*60*24);
	}
	

	public static int diff(Date srcDate, Date destDate) throws CoreException{
		Calendar src = Calendar.getInstance();
		src.setTime(srcDate);
		
		Calendar dest = Calendar.getInstance();
		dest.setTime(destDate);
		
		if (src.get(Calendar.YEAR) == dest.get(Calendar.YEAR)){
			return dest.get(Calendar.DAY_OF_YEAR) - src.get(Calendar.DAY_OF_YEAR);
		} else {
			int srcYear = src.get(Calendar.YEAR);
			
			Calendar tmp = Calendar.getInstance();
			tmp.setTimeInMillis(dest.getTimeInMillis());
			tmp.set(Calendar.YEAR, srcYear);
			
			int diff = tmp.get(Calendar.DAY_OF_YEAR) - src.get(Calendar.DAY_OF_YEAR);
			diff += (destDate.getTime()-tmp.getTimeInMillis())/(1000*60*60*24L);
			
			return diff;
		}
	}
	
	/**
	 * Return today with pattern.
	 * 
	 * @return
	 */
	public static String today(String pattern) {
		 return format(new Date(), pattern);
	}
	
	public static Date dayAdd(int offset) {
		return dayAdd(new Date(), offset);
	}
	 public static Date dayAdd(Date date, int offset) {
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(date);
		 calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + offset);
		 return calendar.getTime();
	 }
	 public static String dayAdd(String pattern, int offset){
		 Date date = dayAdd(offset);
		 return format(date, pattern);
	 }
	 public static String dayAdd(String src, String pattern, int offset) throws CoreException {
		 Date date = dayAdd(parse(src, pattern), offset);
		 return format(date, pattern);
	 }
	 
	 public static Date hourAdd(Date date, int offset){
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(date);
		 calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + offset);
		 return calendar.getTime();
	 }
	 public static Date hourAdd(int offset){
		 return hourAdd(new Date(), offset);
	 }
	 public static String hourAdd(String pattern, int offset){
		 Date date = hourAdd(offset);
		 return format(date, pattern);
	 }
	 public static String hourAdd(String src, String pattern, int offset) throws CoreException {
		 Date date = hourAdd(parse(src, pattern), offset);
		 return format(date, pattern);
	 }
	 
	 public static Date monthAdd(Date date, int offset){
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(date);
		 calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + offset);
		 calendar.set(Calendar.DAY_OF_MONTH, calendar.getMinimum(Calendar.DATE));
		 return calendar.getTime();
	 }
	 public static Date monthAdd(int offset){
		 return monthAdd(new Date(), offset);
	 }
	 public static String monthAdd(String pattern, int offset) {
		 Date date = monthAdd(offset);
		 return format(date, pattern);
	 }
	 public static String monthAdd(String src, String pattern, int offset) throws CoreException {
		 Date date = monthAdd(parse(src, pattern), offset);
		 return format(date, pattern);
	 }
	 
	 public static String getFirstDay(Date month, String destPattern){
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(month);
		 calendar.set(Calendar.DAY_OF_MONTH, calendar.getMinimum(Calendar.DATE));
		 return format(calendar.getTime(), destPattern);
	 }
	 public static String getFirstDay(String month, String srcPattern, String destPattern) throws CoreException{
		 return getFirstDay(parse(month, srcPattern),destPattern);
	 }
	 public static String getLastDay(Date month, String pattern){
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(month);
		 calendar.set(Calendar.DAY_OF_MONTH, calendar.getMaximum(Calendar.DATE));
		 return format(calendar.getTime(), pattern);
	 }
	 public static String getLastDay(String month, String srcPattern, String destPattern) throws CoreException{
		 return getLastDay(parse(month, srcPattern),destPattern);
	 }
}
